﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RzCorportativo.DataAccess;

namespace RzCorportativo.Lib
{
    public class Login
    {
        public Login()
        {
            this.Grupos = new List<Grupo>();
        }

        public int LoginId { get; set; }
        public string LoginText { get; set; }
        public string Senha { get; set; }
        public Lib.Usuario Usuario { get; set; }
        public long UsuarioId { get; set; }
        public Grupo Grupo { get; set; }
        public bool IsNew { get { return this.LoginId == 0; } }
        private bool _statusChanged;
        private bool status;
        public bool Status { get { return this.status; } set { this._statusChanged = true; this.status = value; } }
        RzCorportativo.DataAccess.Login model;
        public bool CadastroCompleto { get; internal set; }
        public TipoLogin TipoLogin { get; set; }
        public List<Lib.Grupo> Grupos { get; set; }

        public static Login CreateInstance(int loginId)
        {
            Login e = new Login();
            RzCorportativo.DataAccess.SistemaCurricularEntities db = new SistemaCurricularEntities();
            var p = db.Login.Where(w => w.LoginId == loginId).FirstOrDefault();
            if (p != null)
                e = e.CreateLogin(p);
            return e;
        }

        public void Notificar(Notificacao notificacao)
        {
            notificacao.EnviarEmail = true;
            notificacao.Login = this;
            notificacao.LoginId = this.LoginId;
            notificacao.Salvar();
        }

        public bool Salvar()
        {
            Lib.Grupo grupo = new Grupo();
            bool @result = false;
            Transaction.Begin((entity) =>
            {
                if (this.IsNew && entity.Login.Any(any => any.Nick.Equals(this.LoginText)))
                    throw new Exception("Login já cadastrado");
                if (this.IsNew)
                {
                    if (this.TipoLogin == Lib.TipoLogin.Candidato || this.TipoLogin == Lib.TipoLogin.Empresa)
                    {
                        grupo.GrupoId = (int)this.TipoLogin;
                        var g = Lib.Grupo.Listar(grupo).FirstOrDefault();
                        if (g == null)
                            throw new Exception("Grupo " + grupo.Descricao + " não cadastrado");
                        grupo = g;
                    }
                    this.model = this.Insert(entity);
                }
                else
                    this.model = this.Update(entity);
                return true;
            }).OnError((ex) =>
            {
                @result = false;
                throw ex;
            }).OnSuccess(() =>
            {
                @result = true;

                if (this.TipoLogin == Lib.TipoLogin.Candidato || this.TipoLogin == Lib.TipoLogin.Empresa)
                {
                    this.LoginId = model.LoginId;
                    bool result2 = grupo.AddUser(this);
                    if (result2)
                        this.Grupos.Add(grupo);
                }

                this.LoginId = this.model.LoginId;
            });

            return @result;
        }

        private DataAccess.Login Insert(SistemaCurricularEntities entity)
        {
            var @item = this.CreateModel(entity);
            entity.AddToLogin(@item);
            return @item;
        }

        private DataAccess.Login Update(SistemaCurricularEntities entity)
        {
            var @item = this.CreateModel(entity);
            return @item;
        }

        private DataAccess.Login CreateModel(SistemaCurricularEntities entity)
        {
            var login = new DataAccess.Login();
            if (!this.IsNew)
            {
                login = entity.Login.Where(w => w.LoginId == this.LoginId).FirstOrDefault();
                if (login == null)
                    throw new Exception("Código inválido");
            }
            login.LoginId = this.LoginId;
            login.Nick = this.IsNew ? this.LoginText.ToLower() : string.IsNullOrEmpty(this.LoginText) ? login.Nick : this.LoginText;
            //login.UsuarioId = this.UsuarioId;
            login.Senha = this.IsNew ? this.Senha : string.IsNullOrEmpty(this.Senha) ? login.Senha : this.Senha;
            login.Ativo = this.status;
            login.TipoLogin = (short)this.TipoLogin;
            return login;
        }

        internal Lib.Login CreateLogin(RzCorportativo.DataAccess.Login item)
        {
            Login model = new Login();
            model.LoginId = item.LoginId;
            model.LoginText = item.Nick;
            model.Usuario = new Lib.Usuario().Create(item.Usuario.FirstOrDefault());
            model.Status = item.Ativo;
            model.TipoLogin = (Lib.TipoLogin)item.TipoLogin;
            model.CadastroCompleto = model.Usuario != null;
            model.Senha = item.Senha;
            if (model.Usuario == null)
                model.Usuario = new Usuario();
            if (item.Grupo != null)
            {
                Grupo g = new Lib.Grupo();
                model.Grupos = new List<Grupo>(item.Grupo.Select(s => g.CreateGrupo(s, false)).ToList());
            }
            return model;
        }

        public static List<Login> Listar(Login login)
        {
            if (login == null)
                login = new Login();
            List<Login> especialidades = new List<Login>();
            RzCorportativo.DataAccess.SistemaCurricularEntities db = new SistemaCurricularEntities();
            bool userIsNull = login.Usuario == null;
            if (userIsNull)
            {
                login.Usuario = new Usuario();
            }
            var user = login.Usuario;
            especialidades = db.Login.Where(w =>
                    (((int)login.TipoLogin == 0) || (w.TipoLogin == (short)login.TipoLogin)) &&
                    ((login.LoginId == 0) || (login.LoginId == w.LoginId)) &&
                    ((login.LoginText == null || login.LoginText == "") || (w.Nick.StartsWith(login.LoginText))) &&
                    ((login.Senha == null || login.Senha == "") || (login.Senha == w.Senha)) &&
                    ((!login._statusChanged) || (login.Status == w.Ativo)) &&
                    (/*userIsNull || */(!w.Usuario.Any() || w.Usuario.Any(a => (user.Nome == null  || user.Nome == "" || a.Nome.StartsWith(user.Nome)) &&
                        (user.UsuarioId == 0 || user.UsuarioId == a.UsuarioId) &&
                        (login.UsuarioId == 0 || login.UsuarioId == a.UsuarioId))
                    ))
                ).ToList().Select(s => login.CreateLogin(s)).ToList().Where(
                    w => userIsNull || (login.Usuario.Nome == null || login.Usuario.Nome == "" || w.Usuario.Nome.ToLower().Contains(login.Usuario.Nome.ToLower())) &&
                        (login.Usuario.Cpf == null || login.Usuario.Cpf == "" || w.Usuario.Cpf == login.Usuario.Cpf)
                    ).ToList();
            return especialidades;
        }
    }
}
